{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<center><img src=\"../image/CLBLOGO.jpg\" alt=\"创乐博\" style=\"width: 300px;\"/></center>\n",
    "\n",
    "# 9.机器人球体追踪\n",
    "\n",
    "@－－－－湖南创乐博智能科技有限公司－－－－<br>\n",
    "@  文件名：8.机器人球体追踪.ipynb <br>\n",
    "@  版本：V2.0 <br>\n",
    "@  author: zhulin<br>\n",
    "@  说明：机器人球体追踪<br>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import cv2\n",
    "import numpy as np\n",
    "from LOBOROBOT import LOBOROBOT # 载入机器人库\n",
    "from gpiozero import Button\n",
    "from gpiozero import LED\n",
    "import time  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "kernel = np.ones((5,5),np.uint8)\n",
    "# 按键及LED初始化\n",
    "Btn  = Button(19,pull_up=True)   # 按键端口\n",
    "Gpin    = LED(5)\n",
    "Rpin    = LED(6)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "clbrobot = LOBOROBOT()  # 实例化机器人对象\n",
    "\n",
    "# Configure min and max servo pulse lengths\n",
    "servo_min = 150  # Min pulse length out of 4096\n",
    "servo_max = 600  # Max pulse length out of 4096\n",
    "\n",
    "# 频率设置为50hz，适用于舵机系统。\n",
    "clbrobot.set_servo_angle(10,90)  # 底座舵机 90 \n",
    "clbrobot.set_servo_angle(9,30)  # 顶部舵机 30\n",
    "time.sleep(0.5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 打开摄像头"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[0:00:47.554335322] [2113] \u001b[1;32m INFO \u001b[1;37mCamera \u001b[1;34mcamera_manager.cpp:284 \u001b[0mlibcamera v0.1.0+118-563cd78e\n",
      "[0:00:47.562916377] [2150] \u001b[1;32m INFO \u001b[1;37mRPI \u001b[1;34mpisp.cpp:653 \u001b[0mlibpisp version v1.0.2 fa44a258644a 22-11-2023 (21:59:22)\n",
      "[0:00:47.572256618] [2150] \u001b[1;32m INFO \u001b[1;37mRPI \u001b[1;34mpisp.cpp:1112 \u001b[0mRegistered camera /base/axi/pcie@120000/rp1/i2c@80000/ov5647@36 to CFE device /dev/media0 and ISP device /dev/media2 using PiSP variant BCM2712_C0\n",
      "[0:00:47.574078618] [2113] \u001b[1;32m INFO \u001b[1;37mCamera \u001b[1;34mcamera_manager.cpp:284 \u001b[0mlibcamera v0.1.0+118-563cd78e\n",
      "[0:00:47.582799303] [2153] \u001b[1;32m INFO \u001b[1;37mRPI \u001b[1;34mpisp.cpp:653 \u001b[0mlibpisp version v1.0.2 fa44a258644a 22-11-2023 (21:59:22)\n",
      "[0:00:47.592514507] [2153] \u001b[1;32m INFO \u001b[1;37mRPI \u001b[1;34mpisp.cpp:1112 \u001b[0mRegistered camera /base/axi/pcie@120000/rp1/i2c@80000/ov5647@36 to CFE device /dev/media0 and ISP device /dev/media2 using PiSP variant BCM2712_C0\n",
      "[0:00:47.595024673] [2113] \u001b[1;33m WARN \u001b[1;37mV4L2 \u001b[1;34mv4l2_pixelformat.cpp:338 \u001b[0mUnsupported V4L2 pixel format Y16 \n",
      "[0:00:47.595070599] [2113] \u001b[1;33m WARN \u001b[1;37mV4L2 \u001b[1;34mv4l2_pixelformat.cpp:338 \u001b[0mUnsupported V4L2 pixel format RGB6\n",
      "[0:00:47.595076822] [2113] \u001b[1;33m WARN \u001b[1;37mV4L2 \u001b[1;34mv4l2_pixelformat.cpp:338 \u001b[0mUnsupported V4L2 pixel format BGR6\n",
      "[0:00:47.595083822] [2113] \u001b[1;33m WARN \u001b[1;37mV4L2 \u001b[1;34mv4l2_pixelformat.cpp:338 \u001b[0mUnsupported V4L2 pixel format PC1M\n",
      "[0:00:47.595772229] [2113] \u001b[1;32m INFO \u001b[1;37mCamera \u001b[1;34mcamera.cpp:1183 \u001b[0mconfiguring streams: (0) 320x240-RGB888 (1) 1920x1080-SRGGB16\n",
      "[0:00:47.595856766] [2153] \u001b[1;32m INFO \u001b[1;37mRPI \u001b[1;34mpisp.cpp:1396 \u001b[0mSensor: /base/axi/pcie@120000/rp1/i2c@80000/ov5647@36 - Selected sensor format: 1920x1080-SRGGB10_1X10 - Selected CFE format: 1920x1080-RG16\n"
     ]
    }
   ],
   "source": [
    "import libcamera\n",
    "from picamera2 import Picamera2\n",
    "\n",
    "picamera = Picamera2()\n",
    "config = picamera.create_preview_configuration(main={\"format\": 'RGB888', \"size\": (320, 240)},\n",
    "                                               raw={\"format\": \"SRGGB12\", \"size\": (1920, 1080)})\n",
    "config[\"transform\"] = libcamera.Transform(hflip=0, vflip=1)\n",
    "picamera.configure(config)\n",
    "picamera.start()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "472fd2eeb0b64b6095691ee449992dc9",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "HBox(children=(Image(value=b'', format='jpeg', height='240', width='320'), Image(value=b'', format='jpeg', hei…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import traitlets\n",
    "import ipywidgets.widgets as widgets\n",
    "from IPython.display import display\n",
    "\n",
    "def bgr8_to_jpeg(value, quality=75):\n",
    "    return bytes(cv2.imencode('.jpg', value)[1])\n",
    "\n",
    "FGmaskComp_img = widgets.Image(format='jpeg', width=320, height=240)\n",
    "frame_img = widgets.Image(format='jpeg', width=320, height=240)\n",
    "\n",
    "dispaly_img = widgets.HBox([FGmaskComp_img,frame_img])\n",
    "display(dispaly_img)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 线程函数操作库\n",
    "import threading # 线程\n",
    "import ctypes\n",
    "import inspect\n",
    "\n",
    "# 线程结束代码\n",
    "def _async_raise(tid, exctype):\n",
    "    tid = ctypes.c_long(tid)\n",
    "    if not inspect.isclass(exctype):\n",
    "        exctype = type(exctype)\n",
    "    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))\n",
    "    if res == 0:\n",
    "        raise ValueError(\"invalid thread id\")\n",
    "    elif res != 1:\n",
    "        ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)\n",
    "        raise SystemError(\"PyThreadState_SetAsyncExc failed\")\n",
    "        \n",
    "def stop_thread(thread):\n",
    "    _async_raise(thread.ident, SystemExit)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "69dc93aef51e459d81bb3b00edcc60ec",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "VBox(children=(HBox(children=(IntSlider(value=20, description='hueLower：', max=179, min=12), IntSlider(value=3…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "hueLower = widgets.IntSlider(min=12,max=179,step=1,description='hueLower：',value=20)\n",
    "hueUpper = widgets.IntSlider(min=30,max=179,step=1,description='hueUpper：',value=30)\n",
    "\n",
    "satLow = widgets.IntSlider(min=50,max=255,step=1,description='satLow：',value=50)\n",
    "satHigh = widgets.IntSlider(min=255,max=255,step=1,description='satHigh：',value=255)\n",
    "\n",
    "valLow = widgets.IntSlider(min=50,max=255,step=1,description='valLow：',value=50)\n",
    "valHigh = widgets.IntSlider(min=255,max=255,step=1,description='valHigh：',value=255)\n",
    "\n",
    "slider_img=widgets.VBox([\n",
    "              widgets.HBox([hueLower,hueUpper]),\n",
    "              widgets.HBox([satLow,satHigh]),\n",
    "              widgets.HBox([valLow,valHigh])\n",
    "             ])\n",
    "display(slider_img)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 按键处理函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 按键标志位\n",
    "keyflag = 0\n",
    "\n",
    "# 按键控制函数\n",
    "def keysacn():\n",
    "    global keyflag\n",
    "    print('*****************************************') \n",
    "    print('* makerobo Button Pressed!*') \n",
    "    print('*****************************************')\n",
    "    Rpin.on()  # 打开红色LED\n",
    "    Gpin.off() # 关闭绿色LED\n",
    "    keyflag = 1   # 按键标志位置1\n",
    "\n",
    "def released():\n",
    "    print(\"button was released\")\n",
    "    Rpin.off()   # 关闭红色LED\n",
    "    Gpin.on()    # 打开绿色LED\n",
    "\n",
    "# 按键中断函数\n",
    "Btn.when_pressed = keysacn\n",
    "Btn.when_released = released"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "def Video_display():\n",
    "    while(1):\n",
    "        if keyflag == 1:\n",
    "            frame = picamera.capture_array()\n",
    "            frame=cv2.flip(frame, 1) \n",
    "            \n",
    "            # 转换到HSV\n",
    "            hsv = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)\n",
    "            hue,sat,val = cv2.split(hsv)\n",
    "            \n",
    "            hueLow=hueLower.value\n",
    "            hueUp=hueUpper.value\n",
    "        \n",
    "            Ls= satLow.value\n",
    "            Us = satHigh.value\n",
    "        \n",
    "            Lv=valLow.value\n",
    "            Uv=valHigh.value\n",
    "        \n",
    "            l_b=np.array([hueLow,Ls,Lv])\n",
    "            u_b=np.array([hueUp,Us,Uv])\n",
    "        \n",
    "        \n",
    "            FGmaskComp=cv2.inRange(hsv,l_b,u_b)\n",
    "            FGmaskComp_img.value = bgr8_to_jpeg(FGmaskComp)\n",
    "            \n",
    "            # 应用阈值\n",
    "            hthresh = cv2.inRange(np.array(hue),np.array(hueLow),np.array(hueUp))\n",
    "            sthresh = cv2.inRange(np.array(sat),np.array(Ls),np.array(Us))\n",
    "            vthresh = cv2.inRange(np.array(val),np.array(Lv),np.array(Uv))\n",
    "        \n",
    "            # h s和v\n",
    "            tracking = cv2.bitwise_and(hthresh,cv2.bitwise_and(sthresh,vthresh))\n",
    "        \n",
    "            # 一些morpholigical过滤\n",
    "            dilation = cv2.dilate(tracking,kernel,iterations = 1)\n",
    "            closing = cv2.morphologyEx(dilation, cv2.MORPH_CLOSE, kernel)\n",
    "            closing = cv2.GaussianBlur(closing,(5,5),0)\n",
    "        \n",
    "            # 使用HoughCircles检测圆\n",
    "            circles = cv2.HoughCircles(closing,cv2.HOUGH_GRADIENT,2,120,param1=120,param2=50,minRadius=10,maxRadius=0)\n",
    "            # circles = np.uint16(np.around(circles))\n",
    "            clbrobot.t_stop(0)\n",
    "        \n",
    "            # 画圆圈\n",
    "            if circles is not None:\n",
    "                x, y, r = circles[0][0]\n",
    "                x_p = int(round(x))\n",
    "                print(x_p)\n",
    "                for i in circles[0,:]:\n",
    "                        # 如果球很远，用绿色画出来\n",
    "                        if int(round(i[2])) < 30:\n",
    "                                cv2.circle(frame,(int(round(i[0])),int(round(i[1]))),int(round(i[2])),(0,255,0),5)\n",
    "                                cv2.circle(frame,(int(round(i[0])),int(round(i[1]))),2,(0,255,0),10)\n",
    "                        # 或者用红色画\n",
    "                        elif int(round(i[2])) > 35:\n",
    "                                cv2.circle(frame,(int(round(i[0])),int(round(i[1]))),int(round(i[2])),(0,0,255),5)\n",
    "                                cv2.circle(frame,(int(round(i[0])),int(round(i[1]))),2,(0,0,255),10)\n",
    "    \n",
    "                # 设定一个范围\n",
    "                x_Lower = 150\n",
    "                x_Upper = 180\n",
    "                # 判断X方向范围来判断机器人的运动\n",
    "                if x_p > x_Lower and x_p < x_Upper:\n",
    "                        clbrobot.t_up(30,0)\n",
    "                elif x_p < x_Lower:\n",
    "                    clbrobot.turnLeft(20,0)              \n",
    "                elif x_p > x_Upper:\n",
    "                    clbrobot.turnRight(20,0)    \n",
    "                else:\n",
    "                    clbrobot.t_stop(0)\n",
    "            # 在帧中显示结果\n",
    "            frame_img.value = bgr8_to_jpeg(frame)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 打开线程"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_2113/3481196328.py:2: DeprecationWarning: setDaemon() is deprecated, set the daemon attribute instead\n",
      "  t.setDaemon(True)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "button was released\n",
      "*****************************************\n",
      "* makerobo Button Pressed!*\n",
      "*****************************************\n",
      "147\n",
      "149\n",
      "137\n",
      "135\n",
      "145\n",
      "149\n",
      "191\n",
      "149\n",
      "149\n",
      "145\n",
      "147\n",
      "147\n",
      "181\n",
      "149\n",
      "135\n",
      "153\n",
      "135\n",
      "151\n",
      "149\n",
      "135\n",
      "141\n",
      "145\n",
      "143\n",
      "133\n",
      "145\n",
      "147\n",
      "145\n",
      "149\n",
      "149\n",
      "147\n",
      "149\n",
      "143\n",
      "147\n",
      "133\n",
      "143\n",
      "147\n",
      "147\n",
      "147\n",
      "147\n",
      "149\n",
      "137\n",
      "149\n",
      "133\n",
      "145\n",
      "133\n",
      "145\n",
      "147\n",
      "143\n",
      "149\n",
      "149\n",
      "147\n",
      "145\n",
      "147\n",
      "135\n",
      "147\n",
      "143\n",
      "149\n",
      "135\n",
      "149\n",
      "143\n",
      "145\n",
      "181\n",
      "153\n",
      "133\n",
      "147\n",
      "135\n",
      "147\n",
      "143\n",
      "149\n",
      "149\n",
      "135\n",
      "135\n",
      "147\n",
      "135\n",
      "143\n",
      "145\n",
      "147\n",
      "143\n",
      "147\n",
      "181\n",
      "149\n",
      "143\n",
      "133\n",
      "133\n",
      "107\n",
      "149\n",
      "147\n",
      "149\n",
      "149\n",
      "157\n",
      "149\n",
      "145\n",
      "149\n",
      "147\n",
      "143\n",
      "147\n",
      "149\n",
      "145\n",
      "147\n",
      "147\n",
      "143\n",
      "143\n",
      "143\n",
      "133\n",
      "147\n",
      "143\n",
      "143\n",
      "151\n",
      "135\n",
      "149\n",
      "133\n",
      "143\n",
      "149\n",
      "143\n",
      "133\n",
      "143\n",
      "143\n",
      "133\n",
      "147\n",
      "149\n",
      "149\n",
      "149\n",
      "147\n",
      "147\n",
      "143\n",
      "143\n",
      "175\n",
      "161\n",
      "137\n",
      "55\n",
      "123\n",
      "161\n",
      "125\n",
      "131\n",
      "123\n",
      "121\n",
      "115\n",
      "107\n",
      "129\n",
      "163\n",
      "169\n",
      "167\n",
      "175\n",
      "173\n",
      "173\n",
      "161\n",
      "163\n",
      "173\n",
      "163\n",
      "159\n",
      "183\n",
      "145\n",
      "149\n",
      "159\n",
      "171\n",
      "163\n",
      "155\n",
      "159\n",
      "161\n",
      "143\n",
      "147\n",
      "153\n",
      "151\n",
      "159\n",
      "161\n",
      "159\n",
      "161\n",
      "151\n",
      "147\n",
      "139\n",
      "141\n",
      "139\n",
      "141\n",
      "137\n",
      "141\n",
      "139\n",
      "151\n",
      "143\n",
      "145\n",
      "141\n",
      "145\n",
      "143\n",
      "139\n",
      "143\n",
      "149\n",
      "145\n",
      "149\n",
      "149\n",
      "151\n",
      "141\n",
      "145\n",
      "149\n",
      "147\n",
      "147\n",
      "151\n",
      "147\n",
      "143\n",
      "161\n",
      "153\n",
      "153\n",
      "145\n",
      "153\n",
      "147\n",
      "141\n",
      "153\n",
      "153\n",
      "157\n",
      "167\n",
      "153\n",
      "153\n",
      "151\n",
      "153\n",
      "153\n",
      "155\n",
      "143\n",
      "137\n",
      "139\n",
      "165\n",
      "159\n",
      "157\n",
      "157\n",
      "153\n",
      "163\n",
      "157\n",
      "151\n",
      "145\n",
      "145\n",
      "141\n",
      "143\n",
      "141\n",
      "139\n",
      "149\n",
      "135\n",
      "133\n",
      "151\n",
      "155\n",
      "139\n",
      "145\n",
      "143\n",
      "145\n",
      "143\n",
      "143\n",
      "141\n",
      "147\n",
      "151\n",
      "141\n",
      "151\n",
      "139\n",
      "159\n",
      "151\n",
      "159\n",
      "143\n",
      "149\n",
      "149\n",
      "151\n",
      "149\n",
      "153\n",
      "157\n",
      "155\n",
      "159\n",
      "155\n",
      "147\n",
      "129\n",
      "131\n",
      "127\n",
      "115\n",
      "123\n",
      "123\n",
      "113\n",
      "121\n",
      "123\n",
      "117\n",
      "123\n",
      "119\n",
      "119\n",
      "119\n",
      "109\n",
      "121\n",
      "117\n",
      "113\n",
      "139\n",
      "125\n",
      "133\n",
      "123\n",
      "119\n",
      "119\n",
      "119\n",
      "109\n",
      "107\n",
      "101\n",
      "107\n",
      "103\n",
      "107\n",
      "103\n",
      "107\n",
      "99\n",
      "99\n",
      "97\n",
      "93\n",
      "91\n",
      "95\n",
      "97\n",
      "85\n",
      "107\n",
      "111\n",
      "133\n",
      "137\n",
      "131\n",
      "135\n",
      "135\n",
      "129\n",
      "113\n",
      "127\n",
      "125\n",
      "123\n",
      "119\n",
      "111\n",
      "105\n",
      "107\n",
      "111\n",
      "115\n",
      "105\n",
      "103\n",
      "103\n",
      "101\n",
      "97\n",
      "93\n",
      "95\n",
      "93\n",
      "95\n",
      "91\n",
      "97\n",
      "99\n",
      "101\n",
      "99\n",
      "103\n",
      "109\n",
      "107\n",
      "105\n",
      "109\n",
      "109\n",
      "115\n",
      "111\n",
      "107\n",
      "111\n",
      "109\n",
      "107\n",
      "101\n",
      "103\n",
      "99\n",
      "97\n",
      "87\n",
      "87\n",
      "85\n",
      "91\n",
      "99\n",
      "95\n",
      "101\n",
      "105\n",
      "111\n",
      "121\n",
      "127\n",
      "123\n",
      "127\n",
      "127\n",
      "129\n",
      "125\n",
      "137\n",
      "121\n",
      "127\n",
      "123\n",
      "115\n",
      "119\n",
      "109\n",
      "103\n",
      "95\n",
      "143\n",
      "139\n",
      "135\n",
      "161\n",
      "131\n",
      "133\n",
      "147\n",
      "135\n",
      "117\n",
      "157\n",
      "297\n",
      "295\n",
      "107\n",
      "109\n",
      "43\n",
      "71\n",
      "49\n",
      "49\n",
      "35\n",
      "127\n",
      "129\n",
      "137\n",
      "137\n",
      "153\n",
      "147\n",
      "129\n",
      "149\n",
      "141\n",
      "133\n",
      "145\n",
      "135\n",
      "131\n",
      "137\n",
      "143\n",
      "135\n",
      "139\n",
      "143\n",
      "145\n",
      "139\n",
      "127\n",
      "147\n",
      "121\n",
      "129\n",
      "131\n",
      "129\n",
      "129\n",
      "149\n",
      "131\n",
      "129\n",
      "127\n",
      "131\n",
      "129\n",
      "137\n",
      "133\n",
      "129\n",
      "135\n",
      "131\n",
      "169\n",
      "161\n",
      "187\n",
      "159\n",
      "197\n",
      "191\n",
      "161\n",
      "121\n",
      "191\n",
      "199\n",
      "165\n",
      "185\n",
      "161\n",
      "279\n",
      "143\n",
      "161\n",
      "131\n",
      "163\n",
      "133\n",
      "197\n",
      "183\n",
      "147\n",
      "161\n",
      "169\n",
      "161\n",
      "163\n",
      "161\n",
      "153\n",
      "161\n",
      "159\n",
      "139\n",
      "143\n",
      "147\n",
      "163\n",
      "143\n",
      "137\n",
      "133\n",
      "163\n",
      "129\n",
      "135\n",
      "125\n",
      "147\n",
      "175\n",
      "129\n",
      "119\n",
      "125\n",
      "105\n",
      "183\n",
      "267\n",
      "143\n",
      "141\n",
      "117\n",
      "197\n",
      "175\n",
      "171\n",
      "181\n",
      "119\n",
      "191\n",
      "99\n",
      "43\n",
      "79\n",
      "303\n",
      "259\n",
      "199\n",
      "179\n",
      "203\n",
      "187\n",
      "173\n",
      "179\n",
      "171\n",
      "177\n",
      "153\n",
      "217\n",
      "227\n",
      "255\n",
      "65\n",
      "301\n",
      "243\n",
      "215\n",
      "153\n",
      "165\n",
      "131\n",
      "169\n",
      "259\n",
      "267\n",
      "199\n",
      "189\n",
      "185\n",
      "169\n",
      "137\n",
      "125\n",
      "167\n",
      "229\n",
      "249\n",
      "255\n",
      "241\n",
      "219\n",
      "167\n",
      "107\n",
      "91\n",
      "101\n",
      "151\n",
      "185\n",
      "213\n",
      "209\n",
      "173\n",
      "145\n",
      "107\n",
      "167\n",
      "181\n",
      "169\n",
      "171\n",
      "181\n",
      "187\n",
      "191\n",
      "155\n",
      "151\n",
      "167\n",
      "171\n",
      "171\n",
      "159\n",
      "117\n",
      "103\n",
      "263\n",
      "251\n",
      "255\n",
      "207\n",
      "193\n",
      "157\n",
      "131\n",
      "275\n",
      "295\n",
      "265\n",
      "235\n",
      "201\n",
      "163\n",
      "127\n",
      "89\n",
      "169\n",
      "221\n",
      "267\n",
      "251\n",
      "233\n",
      "201\n",
      "157\n",
      "139\n",
      "87\n",
      "99\n",
      "121\n",
      "237\n",
      "257\n",
      "223\n",
      "189\n",
      "129\n",
      "103\n",
      "95\n",
      "153\n",
      "175\n",
      "221\n",
      "235\n",
      "153\n",
      "169\n",
      "235\n",
      "237\n",
      "257\n",
      "239\n",
      "195\n",
      "157\n",
      "123\n",
      "135\n",
      "161\n",
      "133\n",
      "101\n",
      "91\n",
      "145\n",
      "211\n",
      "233\n",
      "189\n",
      "175\n",
      "167\n",
      "147\n",
      "167\n",
      "183\n",
      "257\n",
      "171\n",
      "169\n",
      "149\n",
      "275\n",
      "261\n",
      "241\n",
      "201\n",
      "169\n",
      "123\n",
      "115\n",
      "135\n",
      "233\n",
      "265\n",
      "261\n",
      "271\n",
      "237\n",
      "215\n",
      "173\n",
      "121\n",
      "127\n",
      "151\n",
      "239\n",
      "291\n",
      "263\n",
      "213\n",
      "183\n",
      "159\n",
      "115\n",
      "69\n",
      "73\n",
      "111\n",
      "155\n",
      "185\n",
      "213\n",
      "207\n",
      "173\n",
      "89\n",
      "75\n",
      "127\n",
      "181\n",
      "253\n",
      "221\n",
      "201\n",
      "205\n",
      "195\n",
      "167\n",
      "133\n",
      "113\n",
      "107\n",
      "173\n",
      "205\n",
      "245\n",
      "197\n",
      "193\n",
      "113\n",
      "105\n",
      "99\n",
      "117\n",
      "173\n",
      "205\n",
      "245\n",
      "235\n",
      "185\n",
      "163\n",
      "59\n",
      "83\n",
      "145\n",
      "165\n",
      "211\n",
      "319\n",
      "315\n",
      "299\n",
      "233\n",
      "205\n",
      "177\n",
      "145\n",
      "115\n",
      "131\n",
      "171\n",
      "195\n",
      "209\n",
      "197\n",
      "151\n",
      "129\n",
      "129\n",
      "239\n",
      "237\n",
      "205\n",
      "213\n",
      "183\n",
      "177\n",
      "89\n",
      "109\n",
      "115\n",
      "227\n",
      "225\n",
      "205\n",
      "181\n",
      "157\n",
      "137\n",
      "139\n",
      "143\n",
      "201\n",
      "231\n",
      "245\n",
      "235\n",
      "191\n",
      "157\n",
      "147\n",
      "135\n",
      "153\n",
      "179\n",
      "201\n",
      "239\n",
      "261\n",
      "241\n",
      "153\n",
      "143\n",
      "169\n",
      "157\n",
      "225\n",
      "219\n",
      "211\n",
      "197\n",
      "171\n",
      "177\n",
      "157\n",
      "155\n",
      "111\n",
      "91\n",
      "81\n",
      "179\n",
      "189\n",
      "197\n",
      "195\n",
      "215\n",
      "225\n",
      "233\n",
      "247\n",
      "241\n",
      "243\n",
      "207\n",
      "161\n",
      "113\n",
      "169\n",
      "151\n",
      "87\n",
      "103\n",
      "103\n",
      "135\n",
      "115\n",
      "151\n",
      "179\n",
      "151\n",
      "167\n",
      "195\n",
      "155\n",
      "163\n",
      "147\n",
      "175\n",
      "149\n",
      "103\n",
      "147\n",
      "155\n",
      "195\n",
      "91\n",
      "145\n",
      "137\n",
      "169\n",
      "217\n",
      "107\n",
      "157\n",
      "191\n",
      "177\n",
      "173\n",
      "109\n",
      "171\n",
      "65\n",
      "53\n",
      "213\n",
      "203\n",
      "205\n",
      "199\n",
      "201\n",
      "183\n",
      "105\n",
      "105\n",
      "155\n",
      "121\n",
      "189\n",
      "153\n",
      "143\n",
      "149\n",
      "285\n",
      "265\n",
      "237\n",
      "41\n",
      "141\n",
      "161\n",
      "67\n",
      "133\n",
      "221\n",
      "181\n",
      "97\n",
      "89\n",
      "267\n",
      "127\n",
      "159\n",
      "183\n",
      "109\n",
      "187\n",
      "209\n",
      "129\n",
      "259\n",
      "123\n",
      "123\n",
      "157\n",
      "151\n",
      "151\n",
      "141\n",
      "139\n",
      "167\n",
      "127\n",
      "139\n",
      "157\n",
      "135\n",
      "135\n",
      "123\n",
      "123\n",
      "143\n",
      "123\n",
      "135\n",
      "201\n",
      "137\n",
      "139\n",
      "143\n",
      "111\n",
      "131\n",
      "135\n",
      "135\n",
      "131\n",
      "155\n",
      "123\n",
      "135\n",
      "141\n",
      "145\n",
      "141\n",
      "143\n",
      "141\n",
      "143\n",
      "99\n",
      "155\n",
      "145\n",
      "141\n",
      "137\n",
      "179\n",
      "131\n",
      "153\n",
      "125\n",
      "137\n",
      "125\n",
      "147\n",
      "141\n",
      "141\n",
      "139\n",
      "135\n",
      "129\n",
      "127\n",
      "127\n",
      "137\n",
      "133\n",
      "121\n",
      "157\n",
      "139\n",
      "137\n",
      "117\n",
      "123\n",
      "139\n",
      "123\n",
      "129\n",
      "131\n",
      "121\n",
      "115\n",
      "115\n",
      "51\n",
      "171\n",
      "169\n",
      "185\n",
      "125\n",
      "177\n",
      "175\n"
     ]
    }
   ],
   "source": [
    "t = threading.Thread(target=Video_display)\n",
    "t.setDaemon(True)\n",
    "t.start()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 关闭线程"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "129\n"
     ]
    }
   ],
   "source": [
    "# 结束线程\n",
    "clbrobot.t_stop(0) # 停止电机\n",
    "stop_thread(t)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
